package com.faxsun.service.handlers;

import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;

import javax.annotation.Resource;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.broadleafcommerce.common.currency.domain.BroadleafCurrency;
import org.broadleafcommerce.common.exception.ServiceException;
import org.broadleafcommerce.openadmin.dto.Entity;
import org.broadleafcommerce.openadmin.dto.PersistencePackage;
import org.broadleafcommerce.openadmin.dto.Property;
import org.broadleafcommerce.openadmin.server.service.persistence.PersistenceManager;
import org.broadleafcommerce.openadmin.server.service.persistence.PersistenceManagerEventHandlerAdapter;
import org.broadleafcommerce.openadmin.server.service.persistence.PersistenceManagerEventHandlerResponse;

import com.faxsun.admin.service.type.FSSkuStatus;
import com.faxsun.common.currency.dao.FSCurrencyRateDao;
import com.faxsun.common.currency.domain.FSCurrencyEnum;
import com.faxsun.common.currency.domain.FSCurrencyRate;
import com.faxsun.core.catalog.domain.FSProductImpl;
import com.faxsun.tools.DateHelper;
import com.faxsun.tools.EntityHelper;

/**
 * SKU更新hook，可以CARD执行前后进行的操作
 * 
 * @author zhaoteng.song@faxsun.com
 *
 */
public class UpdateSkuHandler extends PersistenceManagerEventHandlerAdapter {

	@SuppressWarnings("unused")
	private static final Log LOG = LogFactory.getLog(UpdateSkuHandler.class);

	@Resource(name = "fsCurrencyRateDao")
	protected FSCurrencyRateDao currencyRateDao;

	@Override
	public PersistenceManagerEventHandlerResponse preUpdate(
			PersistenceManager persistenceManager,
			PersistencePackage persistencePackage) throws ServiceException {
		setSkuStatus(persistencePackage);
		updatePrice(persistencePackage);

		return new PersistenceManagerEventHandlerResponse()
				.withStatus(PersistenceManagerEventHandlerResponse.PersistenceManagerEventHandlerResponseStatus.NOT_HANDLED);

	}

	@Override
	public PersistenceManagerEventHandlerResponse preAdd(
			PersistenceManager persistenceManager,
			PersistencePackage persistencePackage) throws ServiceException {
		setSkuStatus(persistencePackage);
		updatePrice(persistencePackage);

		return new PersistenceManagerEventHandlerResponse()
				.withStatus(PersistenceManagerEventHandlerResponse.PersistenceManagerEventHandlerResponseStatus.NOT_HANDLED);
	}



	protected void updatePrice(PersistencePackage persistencePackage) {
		Entity entity = persistencePackage.getEntity();

		boolean isSku = EntityHelper.isTargetClass(entity, FSProductImpl.class)
				&& isEntityContainsPropertyOf("defaultSku", entity);

		if (isSku) {

			String priceCurrency = EntityHelper.getFieldFromProperties(entity,
					"defaultSku.priceCurrency");
			String foreignPrice = EntityHelper.getFieldFromProperties(entity,
					"defaultSku.foreignPrice");

			if (priceCurrency != null && !priceCurrency.isEmpty()
					&& foreignPrice != null && !foreignPrice.isEmpty()) {
				BroadleafCurrency currency = FSCurrencyEnum
						.parse(priceCurrency);
				BigDecimal foreignPriceDecimal = new BigDecimal(foreignPrice);

				BroadleafCurrency dest = FSCurrencyEnum.parse("CNY");

				// read currency rate
				FSCurrencyRate rate = this.currencyRateDao.readByCodes(
						currency, dest);
				BigDecimal rateValue = new BigDecimal(1);
				if (rate != null) {
					rateValue = rate.getRate();
				}

				// calculate CNY
				BigDecimal retailPriceDecimal = foreignPriceDecimal
						.multiply(rateValue);
				EntityHelper
						.setFieldFromProperties(entity,
								"defaultSku.retailPrice",
								retailPriceDecimal.toString());

				persistencePackage.setEntity(entity);
			}
		}
	}

	protected void setSkuStatus(PersistencePackage persistencePackage) {
		Entity entity = persistencePackage.getEntity();
		if (this.checkSku(entity) == false)
			return;
		final String activeStartDate = EntityHelper.getFieldFromProperties(
				entity, "defaultSku.activeStartDate");
		final String activeEndDate = EntityHelper.getFieldFromProperties(
				entity, "defaultSku.activeEndDate");
		Date date = Calendar.getInstance().getTime();
		Date startDate = null, endDate = null;
		startDate = DateHelper.parse(activeStartDate, null);
		endDate = DateHelper.parse(activeEndDate, null);

		if (startDate == null && endDate == null) {
			EntityHelper.setFieldFromProperties(entity, "defaultSku.skuStatus",
					FSSkuStatus.UNKNOWN.getType());
		} else if (startDate == null) {
			if (endDate.compareTo(date) >= 0) {
				EntityHelper.setFieldFromProperties(entity,
						"defaultSku.skuStatus", FSSkuStatus.SHELVES.getType());
			} else {
				EntityHelper
						.setFieldFromProperties(entity, "defaultSku.skuStatus",
								FSSkuStatus.UNSHELVES.getType());
			}

		} else if (endDate == null) {
			if (startDate.compareTo(date) <= 0) {
				EntityHelper.setFieldFromProperties(entity,
						"defaultSku.skuStatus", FSSkuStatus.SHELVES.getType());
			} else {
				EntityHelper.setFieldFromProperties(entity,
						"defaultSku.skuStatus",
						FSSkuStatus.BEFORE_SHELVES.getType());
			}

		} else {
			if (startDate.compareTo(date) > 0) {
				EntityHelper.setFieldFromProperties(entity,
						"defaultSku.skuStatus",
						FSSkuStatus.BEFORE_SHELVES.getType());
			} else if (endDate.compareTo(date) < 0) {
				EntityHelper
						.setFieldFromProperties(entity, "defaultSku.skuStatus",
								FSSkuStatus.UNSHELVES.getType());
			} else {
				EntityHelper.setFieldFromProperties(entity,
						"defaultSku.skuStatus", FSSkuStatus.SHELVES.getType());
			}
		}

	}

	private boolean checkSku(Entity entity) {
		return EntityHelper.isTargetClass(entity, FSProductImpl.class)
				&& isEntityContainsPropertyOf("defaultSku", entity);
	}

	protected static boolean isEntityContainsPropertyOf(String propertyName,
			Entity entity) {
		for (Property property : entity.getProperties()) {
			if (property.getName().contains(propertyName)) {
				return true;
			}
		}
		return false;
	}

}
